package GUI;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;

import Verwaltung.Daten.Interfaces.IKlasse;
import Verwaltung.Rechtecontroler.PermissionException;

/**
 * 
 * @author MaximumDataOverdrive
 * 
 */
public class KlassenEditDialog extends JDialog implements ActionListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = -619496125209207140L;
	private JLabel lblName;
	private JTextField jNameTextField;
	private JComboBox<String> comboBox;
	private JSeparator separator;
	private JPanel panel;
	private JButton btnLschen;
	private JButton btnNeu;
	private JButton btnAbbrechen;
	private JButton btnSpeichern_1;

	/**
	 * Konstruktor des Klassen-Editier-Dialoges
	 */
	public KlassenEditDialog(final JFrame frame) {
		super(frame);
		setVisible(false);
		initialize();
	}

	/**
	 * Diese Methode initialisert die GUI des Klassen-Editier-Dialoges
	 */
	private void initialize() {
		final GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[] { 0, 0, 0 };
		gridBagLayout.rowHeights = new int[] { 0, 0, 0, 0, 21, 0 };
		gridBagLayout.columnWeights = new double[] { 0.0, 1.0, Double.MIN_VALUE };
		gridBagLayout.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0,
				Double.MIN_VALUE };
		getContentPane().setLayout(gridBagLayout);
		final GridBagConstraints gbc_comboBox = new GridBagConstraints();
		gbc_comboBox.gridwidth = 2;
		gbc_comboBox.insets = new Insets(0, 0, 5, 0);
		gbc_comboBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_comboBox.gridx = 0;
		gbc_comboBox.gridy = 0;
		getContentPane().add(getComboBox(), gbc_comboBox);
		final GridBagConstraints gbc_separator = new GridBagConstraints();
		gbc_separator.gridwidth = 2;
		gbc_separator.insets = new Insets(0, 0, 5, 0);
		gbc_separator.gridx = 0;
		gbc_separator.gridy = 1;
		getContentPane().add(getSeparator(), gbc_separator);
		final GridBagConstraints gbc_lblName = new GridBagConstraints();
		gbc_lblName.insets = new Insets(5, 5, 5, 5);
		gbc_lblName.anchor = GridBagConstraints.EAST;
		gbc_lblName.gridx = 0;
		gbc_lblName.gridy = 2;
		getContentPane().add(getLblName(), gbc_lblName);
		final GridBagConstraints gbc_jNameTextField = new GridBagConstraints();
		gbc_jNameTextField.insets = new Insets(0, 0, 5, 0);
		gbc_jNameTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_jNameTextField.gridx = 1;
		gbc_jNameTextField.gridy = 2;
		getContentPane().add(getJNameTextField(), gbc_jNameTextField);
		final GridBagConstraints gbc_panel = new GridBagConstraints();
		gbc_panel.gridwidth = 2;
		gbc_panel.insets = new Insets(0, 0, 0, 5);
		gbc_panel.fill = GridBagConstraints.BOTH;
		gbc_panel.gridx = 0;
		gbc_panel.gridy = 4;
		getContentPane().add(getPanel(), gbc_panel);
	}

	/**
	 * Diese Methode gibt das Label mit "Name" zurück. Gibt es dieses nicht,
	 * wird es neu initialisert.
	 * 
	 * @return lblName Label indem "Name" steht.
	 */
	private JLabel getLblName() {
		if (lblName == null) {
			lblName = new JLabel("Name");
		}
		return lblName;
	}

	/**
	 * Diese Methode gibt das Text-Feld für den Namen der Klasse zurück. Gibt es
	 * dieses nicht, wird es neu initialisert.
	 * 
	 * @return jNameTextField Text-Feld indem der Name der Klasse steht
	 */
	private JTextField getJNameTextField() {
		if (jNameTextField == null) {
			jNameTextField = new JTextField();
			jNameTextField.setColumns(10);
		}
		return jNameTextField;
	}

	/**
	 * Diese Methode gibt die ComboBox mit den Klassen zurück, die in der
	 * Datenbank vorhanden sind. Gibt es diese nicht, wird diese neu
	 * initialisert.
	 * 
	 * @return comboBox ComboBox mit Klassen die in der Datenbank vorhanden
	 *         sind.
	 */
	private JComboBox<String> getComboBox() {
		if (comboBox == null) {
			comboBox = new JComboBox<String>();

			try {
				updateCombobox();
				comboBox.addActionListener(this);
				if(comboBox.getModel().getSize() > 0) {
					comboBox.setSelectedIndex(0);
				}
			} catch (final PermissionException e) {
				e.printStackTrace();
			}
		}
		return comboBox;
	}

	/**
	 * Diese Methode ist gibt ein optisches Element zurück und erzeugt dieses
	 * gegebenenfalls neu.
	 * 
	 * @return separator Linie
	 */
	private JSeparator getSeparator() {
		if (separator == null) {
			separator = new JSeparator();
		}
		return separator;
	}

	/**
	 * Diese Methode gibt das Panel zurück, der die Buttons für die
	 * Funktionalität des Dialoges enthält. Existiert dieses nicht, wird dieses
	 * neu erzeugt.
	 * 
	 * @return panel Anzeige mit Bedienelementen des Dialoges.
	 */
	private JPanel getPanel() {
		if (panel == null) {
			panel = new JPanel();
			final GridBagLayout gbl_panel = new GridBagLayout();
			gbl_panel.columnWidths = new int[] { 0, 0, 0, 0, 0 };
			gbl_panel.rowHeights = new int[] { 0, 0 };
			gbl_panel.columnWeights = new double[] { 1.0, 1.0, 1.0, 1.0,
					Double.MIN_VALUE };
			gbl_panel.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
			panel.setLayout(gbl_panel);
			final GridBagConstraints gbc_btnLschen = new GridBagConstraints();
			gbc_btnLschen.insets = new Insets(0, 0, 0, 5);
			gbc_btnLschen.gridx = 0;
			gbc_btnLschen.gridy = 0;
			panel.add(getBtnLschen(), gbc_btnLschen);
			final GridBagConstraints gbc_btnSpeichern_1 = new GridBagConstraints();
			gbc_btnSpeichern_1.insets = new Insets(0, 0, 0, 5);
			gbc_btnSpeichern_1.gridx = 1;
			gbc_btnSpeichern_1.gridy = 0;
			panel.add(getBtnSpeichern_1(), gbc_btnSpeichern_1);
			final GridBagConstraints gbc_btnNeu = new GridBagConstraints();
			gbc_btnNeu.insets = new Insets(0, 0, 0, 5);
			gbc_btnNeu.gridx = 2;
			gbc_btnNeu.gridy = 0;
			panel.add(getBtnNeu(), gbc_btnNeu);
			final GridBagConstraints gbc_btnAbbrechen = new GridBagConstraints();
			gbc_btnAbbrechen.gridx = 3;
			gbc_btnAbbrechen.gridy = 0;
			panel.add(getBtnAbbrechen(), gbc_btnAbbrechen);
		}
		return panel;
	}

	/**
	 * Diese Methode gibt den Button: btnLschen zurück. Existiert dieser nicht,
	 * wird er neu initialisert.
	 * 
	 * @return btnLschen Button der bei Betätigung die ausgewählte Klasse
	 *         löschen lässt.
	 */
	private JButton getBtnLschen() {
		if (btnLschen == null) {
			btnLschen = new JButton("Löschen");
			btnLschen.addActionListener(this);
		}
		return btnLschen;
	}

	/**
	 * Diese Methode gibt den Button: btnNeu zurück. Existiert dieser nicht,
	 * wird er neu initialisert.
	 * 
	 * @return btnNeu Button der die Anzeige zur Erzeugung einer neuen Klasse
	 *         öffnet.
	 */
	private JButton getBtnNeu() {
		if (btnNeu == null) {
			btnNeu = new JButton("Neu");
			btnNeu.addActionListener(this);
		}
		return btnNeu;
	}

	/**
	 * Diese Methode gibt den Button: btnAbbrechen zurück. Existiert dieser
	 * nicht, wird er neu initialisert.
	 * 
	 * @return btnAbbrechen Button der die Editierung einer neuen Klasse
	 *         abbricht.
	 */
	private JButton getBtnAbbrechen() {
		if (btnAbbrechen == null) {
			btnAbbrechen = new JButton("Abbrechen");
			btnAbbrechen.addActionListener(this);
		}
		return btnAbbrechen;
	}

	/**
	 * Diese Methode enthält alle Funktionen, die bei der Betätigung der
	 * jeweiligen Elemente ausgeführt werden. Dabei wird bei den if-Bedigungen
	 * geprüft, welches Element betätigt worden ist und die gewünschte Funktion
	 * wird ausgeführt.
	 */
	@Override
	public void actionPerformed(final ActionEvent av) {
		if (av.getSource() == getBtnAbbrechen()) {

			setVisible(false);
			dispose();
		} else if (av.getSource() == getBtnLschen()) {
			try {
				StundenplanController
						.getInstance()
						.getRechteController()
						.removeKlasse(
								getComboBox().getSelectedItem().toString());
				updateCombobox();
			} catch (final PermissionException e) {
				e.printStackTrace();
			}
			StundenplanController.getInstance().update();
		} else if (av.getSource() == getBtnSpeichern_1()) {
			try {
				
				if(getComboBox().getSelectedItem() == null) {
					return;
				}
				
				StundenplanController
						.getInstance()
						.getRechteController()
						.editKlasse(getComboBox().getSelectedItem().toString(),
								getJNameTextField().getText());
				updateCombobox();
				
				dispose();
			} catch (final PermissionException e) {
				e.printStackTrace();
			}

			StundenplanController.getInstance().update();
		} else if (av.getSource() == getBtnNeu()) {
			try {

				final String s = (String) JOptionPane
						.showInputDialog(
								this,
								"Den neuen eindeutigen Namen der Klasse eingeben",
								"Klasse Neu", JOptionPane.PLAIN_MESSAGE, null,
								null, "");

				// If a string was returned, say so.
				if ((s != null) && (s.length() > 0)) {
					
					if(StundenplanController.getInstance()
							.getRechteController().getKlasse(s) != null) {
						JOptionPane.showMessageDialog(this, "Loginname schon vergeben");
						return;
					}

					StundenplanController.getInstance().getRechteController()
							.addKlasse(s);
					// erfolg signalisieren
					updateCombobox();
					StundenplanController.getInstance().update();
					return;
				}

			} catch (final PermissionException e) {
				// TODO Handle exception
				// erfolg angeben fehler ausgeben
				e.printStackTrace();
			}
			StundenplanController.getInstance().update();
		} else if (av.getSource() == getComboBox()) {

			if (getComboBox().getSelectedItem() != null) {
				getJNameTextField().setText(
						getComboBox().getSelectedItem().toString());
			}
		}

	}

	/**
	 * Diese Methode realisert das Updaten der Einträge in der ComboBox. Sie
	 * lädt also alle aktuell existierenden Klassen hinein.
	 * 
	 * @throws PermissionException
	 *             Da die Exception bei Methoden des Rechtecontrolers geworfen
	 *             wird.
	 */
	private void updateCombobox() throws PermissionException {

		// //getComboBox().removeActionListener(this);

		final Object selected = getComboBox().getSelectedItem();

		final DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) getComboBox()
				.getModel();
		model.removeAllElements();

		for (final IKlasse klasse : StundenplanController.getInstance()
				.getRechteController().getAlleKlassen()) {
			model.addElement(klasse.getName());
		}

		if (selected != null) {
			getComboBox().setSelectedItem(selected);
		}
		// getComboBox().addActionListener(this);

	}

	/**
	 * Diese Methode gibt den Button: btnSpeichern_1 zurück. Existiert dieser
	 * nicht, wird er neu initialisert.
	 * 
	 * @return btnSpeichern_1 Button der die Editierung einer Klasse speichert.
	 */
	private JButton getBtnSpeichern_1() {
		if (btnSpeichern_1 == null) {
			btnSpeichern_1 = new JButton("Speichern");
			btnSpeichern_1.addActionListener(this);
		}
		return btnSpeichern_1;
	}
}
